package ca.cbc.medialib.service;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.matchers.JUnitMatchers.hasItem;

import java.sql.SQLException;
import java.util.*;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.operation.DatabaseOperation;
import org.hamcrest.Matchers;
import org.hibernate.Hibernate;
import org.hibernate.classic.Session;
import org.junit.*;

import ca.cbc.medialib.entity.Category;
import ca.cbc.medialib.entity.FailedMedia;
import ca.cbc.medialib.entity.Media;
import ca.cbc.medialib.util.HibernateUtil;

public class MediaStorageServiceImplTestRead {

    private MediaStorageService mss = new MediaStorageServiceImpl();

    @After
    public void after() {
    	HibernateUtil.commitTransaction();
        HibernateUtil.shutdown();
    }

    @Test
    public void sss() {
    	System.out.println("adfd");
    }
    
    @Test
    public void testGetCategoryByFullTitle2() {
    	HibernateUtil.getSession().setDefaultReadOnly(true);
    	String fullTitle = "Shows";
        Category cat = mss.getCategoryByFullTitle(fullTitle);
        Category subCat = mss.getCategoryByFullTitle("Shows/" + fullTitle);
        
        if(cat == null && subCat == null){
        	System.out.println("Error");
        } else if(cat == null && subCat != null) {
        	cat = subCat;
        } else if(cat != null && subCat != null) {            

            System.out.println(cat.getMedias().size());
            for(Media m : subCat.getMedias()) {
            	cat.getMedias().add(m);
            	System.out.println(m.getTitle());
            }
            System.out.println(cat.getMedias().size());
            for(Media m : cat.getMedias()) {
            	System.out.println("media---------" + m.getId() + ", " + m.getTitle());
            	for(Category c : m.getCategories()) {
            		System.out.println(c.getId() + ", " + c.getFullTitle());
            	}
            }
        }
    }   
    
    @Test
    public void testGetCategoryByFullTitle() {
    	String fullTitle = "Shows";
    	HibernateUtil.getSession().setDefaultReadOnly(true);
        Category cat = mss.getCategoryByFullTitle(fullTitle);
        Category subCat = mss.getCategoryByFullTitle("Shows/" + fullTitle);
        
//        HibernateUtil.getSession().setReadOnly(cat, true);
//        HibernateUtil.getSession().setReadOnly(subCat, true);
        
        
        if(cat == null && subCat == null){
        	System.out.println("Error");
        } else if(cat == null && subCat != null) {
        	cat = subCat;
        } else if(cat != null && subCat != null) {
        	cat.removeChild(subCat);
        	for(Category c : subCat.getChildren()) {
        		cat.getChildren().add(c);
        	}
        }
    }
    
    @BeforeClass
    public static void setUp() {
//        try {
            HibernateUtil.createSessionFactory();
            HibernateUtil.beginTransaction();
//            // initialize your database connection here
//            IDatabaseConnection connection = null;
//            connection = new DatabaseConnection(HibernateUtil.getSession().connection());
//            // initialize your dataset here
//
//            DatabaseOperation.CLEAN_INSERT.execute(connection, DbUnitTestUtil.getDataSet());
//            HibernateUtil.getSession().getTransaction().commit();
//        } catch (SQLException e) {
//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//        } catch (DatabaseUnitException e) {
//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//        } catch (Exception e) {
//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//        } finally {
//
//        }
    }


    @Test
    public void getCategoryByFullTitleTest() {
        HibernateUtil.beginTransaction();
        Category c = mss.getCategoryByFullTitle("/show/Being Erica/Season 2");
        assertThat("Testing get media", c.getTitle(), equalTo("Season 2"));
        assertThat("Testing get media", c.getFullTitle(), equalTo("/show/Being Erica/Season 2"));
        assertThat("Parent", c.getParent(), Matchers.<Object>notNullValue());
        assertThat("Testing get media", c.getParent().getTitle(), equalTo("Being Erica"));

        HibernateUtil.commitTransaction();
    }

    @Test
    public void getMediaByReleaseIdTest() {
        HibernateUtil.beginTransaction();
        Media m = mss.getMediaByReleaseId(1L);
        assertThat("Testing get media by releaseId", m.getTitle(), equalTo("test1"));
        assertThat("Media categories ", m.getCategories().size(), equalTo(2));
        assertThat("Media categories has an item ", m.getCategories(), hasItem(Matchers.<Category>hasProperty("title", is("Being Erica"))));
        assertThat("Media categories has an item ", m.getCategories(), hasItem(Matchers.<Category>hasProperty("title", is("18 To Life"))));
        HibernateUtil.commitTransaction();
    }


    @Test
    public void listExpiredDownloadMediaTest() {
        HibernateUtil.beginTransaction();
        List<Media> mediaList = mss.listExpiredMedia(0,10);
        HibernateUtil.commitTransaction();
        assertThat("Expired item should have two elements" + Arrays.toString(mediaList.toArray()),
                mediaList.size(), equalTo(2));
        assertThat("Media 1 is missing ", mediaList, hasItem(Matchers.<Media>hasProperty("releaseId", Matchers.is(1L))));
        assertThat("Media 1 is missing ", mediaList, hasItem(Matchers.<Media>hasProperty("releaseId", Matchers.is(4L))));

    }

    @Test
    public void listFailedMediaTest() {
        HibernateUtil.beginTransaction();
        List<FailedMedia> fmList = mss.listFailedMedia();
        HibernateUtil.commitTransaction();
        assertThat("expired has two elements" + Arrays.toString(fmList.toArray()), fmList.size(), equalTo(2));

        assertThat("expired element title", fmList, Matchers.hasItem(Matchers.<FailedMedia>hasProperty("releaseId", Matchers.is(123L))));
        assertThat("expired element title", fmList, Matchers.hasItem(Matchers.<FailedMedia>hasProperty("releaseId", Matchers.is(1234L))));
    }
}
